/**
 * Region.as
 * Andy Jiang   
 * Fusion Digital Shanghai Co,Ltd. All Rights Reserved.
 * version 0.1
 */ 

package jiezi.ui
{
	import flash.events.Event
	import flash.utils.Dictionary;
	import jiezi.log.Logger
	
	public class Region extends ParentedObject
	{
		public static const MOVE:String			= "move";
		public static const RESIZE:String		= "resize";
		
		public static const TOP:uint 			= 1;
		public static const LEFT:uint 			= 2;
		public static const BOTTOM:uint 		= 4;
		public static const RIGHT:uint 			= 8;
		public static const TOPLEFT:uint 		= TOP|LEFT;
		public static const TOPRIGHT:uint 		= TOP|RIGHT;
		public static const BOTTOMLEFT:uint 	= BOTTOM|LEFT;
		public static const BOTTOMRIGHT:uint	= BOTTOM|RIGHT;

		private var mX:uint;
		private var mY:uint;
		private var mWidth:uint;
		private var mHeight:uint;
		private var mAnchorPoints:Array;
		
		public function Region(name:String)
		{
			super(name);
			addEventListener(ATTACH, this.onAttached)
			this.mAnchorPoints = new Array()
			mX = 0;
			mY = 0;
			mWidth = 100;
			mHeight = 100;
		}
	
		public function set x(x:uint):void
		{
			if ( x != mX )
			{
				this.mX = x;
				this.dispatchEvent(new Event(MOVE));
			}
		}
		
		public function get x():uint
		{
			return this.mX
		}
		
		public function set y(y:uint):void
		{
			if ( y != mY  )
			{
				this.mY = y;
				this.dispatchEvent(new Event(MOVE));
			}
		}
		
		public function setPosition( x:uint, y:uint ):void
		{
			if ( x != mX || y != mY)
			{
				mX = x
				mY = y
				this.dispatchEvent(new Event(MOVE))
			}
		}
		
		public function get y():uint
		{
			return this.mY
		}
	
		public function set width(w:uint):void
		{
			if ( mWidth != w )
			{
				this.mWidth = w;
				this.dispatchEvent(new Event(RESIZE));
			}
		}
		
		public function get width():uint
		{
			return this.mWidth
		}
		
		public function set height(h:uint):void
		{
			if ( mHeight != h )
			{
				this.mHeight = h;
				this.dispatchEvent(new Event(Event.RESIZE));
			}
		}
		
		public function get height():uint
		{
			return this.mHeight
		}
		
		public function setSize(w:uint, h:uint):void
		{
			if ( w != mWidth || h != mHeight )
			{
				this.mWidth = w;
				this.mHeight = h;
				this.dispatchEvent(new Event(Event.RESIZE));				
			}
		}
		
		public function setPoint(point:uint, refer_point:uint, x:int=0, y:int=0):void
		{
			var dirty:Boolean = false;
			if ( point & TOP )
			{
				this.mAnchorPoints[TOP] = [refer_point, x, y]
				dirty = true;
			}
			if ( point & LEFT )
			{
				this.mAnchorPoints[LEFT] = [refer_point, x, y]
				dirty = true;
			}
			if ( point & BOTTOM )
			{
				this.mAnchorPoints[BOTTOM] = [refer_point, x, y]
				dirty = true;
			}
			if ( point & RIGHT )
			{
				this.mAnchorPoints[RIGHT] = [refer_point, x, y]
				dirty = true;
			}
			if ( dirty )
			{
				invalidateLayout()
			}
		}
		
		private function invalidateLayout():void
		{
			var _parent:Region = Region(parent)
			var _left:uint = 0;
			var _top:uint = 0;
			var _right:uint = _parent.width;
			var _bottom:uint = _parent.height;
			
			var _newX:uint = mX;
			var _newY:uint = mY;
			var _newWidth:uint = mWidth;
			var _newHeight:uint = mHeight;
			
			for ( var v:* in this.mAnchorPoints )
			{
				var data:* = mAnchorPoints[v]
				switch( v )
				{
					case TOP:
						if ( data[0] & TOP )
						{
							_newY = _top + data[2];
						} else if ( data[0] & BOTTOM )
						{
							_newY = _bottom + data[2];
						}
						break;
					case LEFT:
						if ( data[0] & LEFT )
						{
							_newX = _left + data[1];
						} else if ( data[0] & RIGHT )
						{
							_newX = _right + data[1];
						}
						break;
					case BOTTOM:
						if ( TOP in mAnchorPoints )
						{
							// top is anchored, we should adjust height
							if ( data[0] & TOP )
							{
								_newHeight = _top + data[2] - _newY;
							} else if ( data[0] & BOTTOM )
							{
								_newHeight = _bottom + data[2] - _newY;
							}							
						}
						else
						{
							// top is anchored, we should adjust mY
							if ( data[0] & TOP )
							{
								_newY = _top + data[2] - mHeight;
							} else if ( data[0] & BOTTOM )
							{
								_newY = _bottom + data[2] - mHeight;
							}
						}
						break;
					case RIGHT:
						if ( LEFT in mAnchorPoints )
						{
							// left is anchored, we should adjust width
							if ( data[0] & LEFT )
							{
								_newWidth = _left + data[1] - _newX;
							}
							else if ( data[0] & RIGHT )
							{
								_newWidth = _right + data[1] - _newX;
							}
						}
						else
						{
							// left is not anchored, we should adjust left
							if ( data[0] & LEFT )
							{
								_newX = _left + data[1] - mWidth
							}
							else ( data[0] & RIGHT )
							{
								_newX = _right + data[1] - mWidth
							}
						}
						break;
				}
			}
			
			setPosition(_newX, _newY)
			setSize(_newWidth, _newHeight)
			//Logger.getSingleton().log(v+String(mAnchorPoints[v]))
			
			Logger.getSingleton().log( this.name + " " + mX + " " +mY + " " + mWidth + " " + mHeight )
		}
		
		protected function onAttached(event:Event):void
		{
			parent.addEventListener(RESIZE, this.onParentResized)
		}
		
		protected function onParentResized(event:Event):void
		{
			Logger.getSingleton().log( this.parent.name + " has resized" )
			invalidateLayout()
		}
	}
}